package com.yuncheng.spcyApi.flowService;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.spcyApi.busService.FlowJobBlsxService;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.spcyApi.constant.flow.FlowConstant;
import com.yuncheng.spcyApi.constant.flow.YpscFlowConstant;
import com.yuncheng.spcyApi.entity.SpcySqsxJob;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.spcyApi.service.ISpcySqsxJobService;
import com.yuncheng.spcyApi.utils.GetCurrentUserUtils;

import com.yuncheng.spcyApi.utils.GetUuIdUtils;
import com.yuncheng.vo.CurrentUserVo;
import com.yuncheng.spcyApi.vo.common.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import utils.DateConversionUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component(value = "flowServiceSpcy")
public class FlowService {

    @Resource
    @Lazy
    private FlowJobBlsxService flowJobBlsxService;

    @Resource
    private ISpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private YpscFlowService ypscFlowService;

    @Resource
    @Lazy
    private YpzcFlowService ypzcFlowService;

    @Resource
    @Lazy
    private YpltFlowService ypltFlowService;

    @Resource
    @Lazy
    private YlqxFlowService ylqxFlowService;

    @Resource
    @Lazy
    private HzpFlowService hzpFlowService;

    @Resource
    @Lazy
    private RckpFlowService rckpFlowService;

    @Resource
    @Lazy
    private NdkpFlowService ndkpFlowService;

    @Resource
    @Lazy
    private YbjcyFlowService ybjcyFlowService;

    @Resource
    @Lazy
    private SpcyZjFlowService spcyZjFlowService;

    @Resource
    @Lazy
    private SpBzFlowService spBzFlowService;

    @Resource
    @Lazy
    private ZltxwjFlowService zltxwjFlowService;

    @Resource
    @Lazy
    private JsscbgFlowService jsscbgFlowService;

    @Resource
    @Lazy
    private SpzgqrFlowService spzgqrFlowService;

    @Resource
    @Lazy
    private HfrwFlowService hfrwFlowService;


    //初始化任务,创建好业务记录以后调用
    public Result initJob(FlowConstant flowConstant, String pid, CurrentUserVo currentUser){
        String nodeName = flowConstant.getFirstNode();
        //需要校验是否已经初始化过
        List<SpcySqsxJob> list = spcySqsxJobService.list(new LambdaQueryWrapper<SpcySqsxJob>()
                .eq(SpcySqsxJob::getFpid, pid)
                .eq(SpcySqsxJob::getFhjmc,nodeName)
                .ne(SpcySqsxJob::getFblzt, SpcyConstant.BLZT_YB)
        );

        boolean isSpcyFlow = false;
        if (flowConstant.getFywflcode().equals("001002")) {
            // 药品生产 - 流程
            isSpcyFlow = true;
        } else if (flowConstant.getFywflcode().equals("001001")){
            // 药品注册
            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("001003")){
            // 药品流通
            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("002")){
            // 医疗器械
            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("003")){
            // 化妆品
            isSpcyFlow = true;
        }

        // 初始化-申请事项-办理时限
        if (isSpcyFlow){
            flowJobBlsxService.initSqsxBlsxBySqsxId(pid);
        }

        if(list.size()>0){
           List<String> ids = list.stream().map(SpcySqsxJob::getId).collect(Collectors.toList());
           spcySqsxJobService.removeBatchByIds(ids);
       }
        return createNextJob(flowConstant,pid,null,currentUser,nodeName,"");
    }
    public Result passJob(FlowConstant flowConstant,String pid, String jobId, String opinion,String nextNodeName,String nextNodeDbrIds) {
       return passJob(flowConstant, pid, jobId, opinion, nextNodeName, nextNodeDbrIds,true);
    }

    /**
     * 提交任务
     * @param pid 业务表id
     * @param jobId 待提交的jobId
     * @param opinion 办理意见
     * @param nextNodeName 下一环节名称（可空）
     * @param nextNodeDbrIds 下一环节办理人（可空）
     * @return
     */
    public Result passJob(FlowConstant flowConstant,String pid, String jobId, String opinion,String nextNodeName,String nextNodeDbrIds,boolean isOverCurrentJob){

        // 获得当前待办任务，并做校验
        SpcySqsxJob job= spcySqsxJobService.getById(jobId);
        if (job==null){
            return Result.error("查不到id为【"+jobId+"】的待办任务");
        }

        //获取办理人，并做办理人的校验，如果当前登录人不是待办人之一，拒绝办理
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            return Result.error("请先登录");
        }
        if(isOverCurrentJob){
            this.verifryNextDbr(flowConstant,pid,job,nextNodeName,nextNodeDbrIds);

            //办理掉当前环节
            Result result = doJob(job,currentUser,opinion);
            //生成下一环节的待办
            if(result.isSuccess()){
                job = (SpcySqsxJob)result.getResult();
                if(job.getFblzt().equals(SpcyConstant.BLZT_YB)){
                    //创建下一环节任务
                    Result result1= createNextJob(flowConstant,pid,job,currentUser,nextNodeName,nextNodeDbrIds);
                    if (!result1.isSuccess()){
                        return Result.error(result1.getMessage());
                    }else {
                        // 3-16 返回新增的流程任务
                        return Result.ok(result1.getResult());
                    }
                }
                // 3-16 返回当前流程任务
                return Result.ok(job);
            }else{
                return Result.error(result.getMessage());
            }
        }else{
            //请小陈完善

            //创建下一环节任务
            Result result1= createNextJob(flowConstant,pid,job,currentUser,nextNodeName,nextNodeDbrIds);
            if (!result1.isSuccess()){
                return Result.error(result1.getMessage());
            }else {
                // 3-16 返回新增的流程任务
                return Result.ok(result1.getResult());
            }
        }


    }

    /**
     * 办理流程环节
     * @param job
     * @param currentUser
     */
    private Result doJob(SpcySqsxJob job, CurrentUserVo currentUser, String opinion){
        String blrId = "";
        String blr = "";
        String blbm = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
            blbm = currentUser.getOrgName();
        }

        if(SpcyConstant.BLZT_YB.equals(job.getFblzt())){
            return Result.error("当前任务已提交");
        }

        if(StringUtils.isBlank(job.getFdbrid())){
            return Result.error("当前任务未指定办理人");
        }

        if(!job.getFdbrid().contains(blrId)){
            return Result.error("当前登录用户无此任务的办理权限");
        }

        // 办理方式 竞争办理 、多人线性办理 、多人并行办理
        String blfs = job.getFblfs();
        if(StringUtils.isBlank(blfs)||blfs.equals(SpcyConstant.BLFS_DRJJ)){
            job.setFblr(blr);
            job.setFblsj(new Date());
            job.setFblyj(opinion);
            job.setFblzt(SpcyConstant.BLZT_YB);
            job.setFbllx(SpcyConstant.BLLX_BL);
            job.setFblbm(blbm);

            // 审评查验流程 计算 办理天数、是否超时
            if (StringUtils.isNotBlank(job.getFlcmc())
                    && (
                            job.getFlcmc().contains(YpscFlowConstant.LCMC_LIKE_SPCYLC)
            )) {

                job.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(job.getFksyts(),job.getFpid(),job.getFfssj(), job.getFblsj(), job.getFztkssj(),job.getFztjssj())); // 使用天数
                job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时

            }else {

                job.setFsyts(flowJobBlsxService.jssygzr(job.getFfssj(), job.getFblsj())); // 使用天数
                job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时
            }

            spcySqsxJobService.updateById(job);
            return Result.ok(job);

        }else if(blfs.equals(SpcyConstant.BLFS_DRXX)  || blfs.equals(SpcyConstant.BLFS_DRBX)){
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId ="";
            String nextBlr ="";
            if(blfs.equals(SpcyConstant.BLFS_DRXX)){
                String ydbrIds[] = job.getFydbrid().split(",");
                String ydbrs[] = job.getFydbr().split(",");
                for (int i=0;i<ydbrIds.length;i++){
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(dbrId.equals(blrId)){
                        if(i+1<ydbrIds.length){
                            nextBlrId=ydbrIds[i+1];
                            nextBlr=ydbrs[i+1];
                            break;
                        }
                    }
                }
            }else{
                String dbrIds[] = job.getFdbrid().split(",");
                String dbrs[] = job.getFdbr().split(",");
                for (int i=0;i<dbrIds.length;i++){
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(!dbrId.equals(blrId)){
                        nextBlrId=nextBlrId+(StringUtils.isBlank(nextBlrId)?"":",")+dbrId;
                        nextBlr=nextBlr+(StringUtils.isBlank(nextBlr)?"":",")+dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            job.setFblr(blr);
            job.setFblsj(new Date());
            String blyj=(job.getFblyj()==null?"":job.getFblyj())+(StringUtils.isBlank(job.getFblyj())?"":"@@")+ DateConversionUtils.DateToString(new Date()) +"|"+blr+"|"+ opinion;
            job.setFblyj(blyj);
            if(StringUtils.isBlank(nextBlrId)){
                job.setFblzt(SpcyConstant.BLZT_YB);
                job.setFbllx(SpcyConstant.BLLX_BL);
                job.setFblbm(blbm);
            }else{
                job.setFblzt(SpcyConstant.BLZT_DB);
                job.setFdbrid(nextBlrId);
                job.setFdbr(nextBlr);
            }

            // 审评查验流程 计算 办理天数、是否超时
            if (StringUtils.isNotBlank(job.getFlcmc())
                    && (
                    job.getFlcmc().contains(YpscFlowConstant.LCMC_LIKE_SPCYLC)
            )) {

                job.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(job.getFksyts(),job.getFpid(),job.getFfssj(), job.getFblsj(), job.getFztkssj(),job.getFztjssj())); // 使用天数
                job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时

            }else {

                job.setFsyts(flowJobBlsxService.jssygzr(job.getFfssj(), job.getFblsj())); // 使用天数
                job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时
            }

            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /**
     * 判断下一环节是否存在待办人
     */
    public void verifryNextDbr(FlowConstant flowConstant,String pid,SpcySqsxJob currentJob,String nextNodeName,String nextNodeDbrIds){

        if (currentJob != null) {
            nextNodeName = getNextNodeName(flowConstant, currentJob.getFhjmc(), nextNodeName);
        }else {
            nextNodeName = getNextNodeName(flowConstant, "", nextNodeName);
        }

        if(nextNodeName.equals(flowConstant.HJMC_LCJS)){
            SpcySqsxJob job = new SpcySqsxJob();

            return;
        }

        Map map = new HashMap();
        if (flowConstant.getFywflcode().equals("001002")) {
            // 药品生产 - 流程
            map = ypscFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("001001")){
            // 药品注册
            map = ypzcFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
        }else if (flowConstant.getFywflcode().equals("001003")){
            // 药品流通
            map = ypltFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
        }else if (flowConstant.getFywflcode().equals("002")){
            // 医疗器械
            map = ylqxFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
        }else if (flowConstant.getFywflcode().equals("003")){
            // 化妆品
            map = hzpFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("rckp001")){
            // 日常考评 - 流程
            map = rckpFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("ndkp001")){
            // 年度考评 - 流程
            map = ndkpFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("ybjcy001")){
            // 预备检查员 - 流程
            map = ybjcyFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        }  else if (flowConstant.getFywflcode().equals("zjhshs001")){
            // 专家函审会审流程
            map = spcyZjFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("spbzlc001")){
            // 审评补正流程
            map = spBzFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("zltxwj001")){
            // 质量体系文件流程
            map = zltxwjFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("jsscbglc001")){
            // 技术审查报告流程
            map = jsscbgFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
//            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("spzgqrlc001")){
            // 整改确认流程
            map = spzgqrFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        }else if (flowConstant.getFywflcode().equals("hfrwZhuFLow001")){
            // 回访任务主流程
            map = hfrwFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        }

        nextNodeDbrIds = map.get("dbrId").toString();

        if(StringUtils.isBlank(nextNodeDbrIds)){
            throw new BusinessException("获取不到下一环节待办人");
        }
    }

    /**
     * 创建流程任务
     * @param pid
     * @param currentJob
     * @param currentUser
     * @param nextNodeName
     * @param nextNodeDbrIds
     * @return
     */
    public Result createNextJob(FlowConstant flowConstant,String pid,SpcySqsxJob currentJob, CurrentUserVo currentUser,String nextNodeName,String nextNodeDbrIds){
        if (currentJob != null) {
            nextNodeName = getNextNodeName(flowConstant, currentJob.getFhjmc(), nextNodeName);
        }else {
            nextNodeName = getNextNodeName(flowConstant, "", nextNodeName);
        }
        if(nextNodeName.equals(flowConstant.HJMC_LCJS)){
            SpcySqsxJob job = new SpcySqsxJob();

            return Result.ok(job);
        }

        boolean isSpcyFlow = false;  // 是否为审评查验流程
        Map map = new HashMap();
        if (flowConstant.getFywflcode().equals("001002")) {
            // 药品生产 - 流程
            map = ypscFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
            isSpcyFlow = true;
        } else if (flowConstant.getFywflcode().equals("001001")){
            // 药品注册
            map = ypzcFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("001003")){
            // 药品流通
            map = ypltFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("002")){
            // 医疗器械
            map = ylqxFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("003")){
            // 化妆品
            map = hzpFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
            isSpcyFlow = true;
        } else if (flowConstant.getFywflcode().equals("rckp001")){
            // 日常考评 - 流程
            map = rckpFlowService.getNodeDbr(pid,nextNodeName, nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("ndkp001")){
            // 年度考评 - 流程
            map = ndkpFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("ybjcy001")){
            // 预备检查员 - 流程
            map = ybjcyFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        }  else if (flowConstant.getFywflcode().equals("zjhshs001")){
            // 专家函审会审流程
            map = spcyZjFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
            isSpcyFlow = true;
        } else if (flowConstant.getFywflcode().equals("spbzlc001")){
            // 审评补正流程
            map = spBzFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("zltxwj001")){
            // 质量体系文件流程
            map = zltxwjFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        } else if (flowConstant.getFywflcode().equals("jsscbglc001")){
            // 技术审查报告流程
            map = jsscbgFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
//            isSpcyFlow = true;
        }else if (flowConstant.getFywflcode().equals("spzgqrlc001")){
            // 整改确认流程
            map = spzgqrFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        }else if (flowConstant.getFywflcode().equals("hfrwZhuFLow001")){
            // 回访任务主流程
            map = hfrwFlowService.getNodeDbr(pid,nextNodeName,nextNodeDbrIds);
        }

        nextNodeDbrIds = map.get("dbrId").toString();
        String nextNodeDbrs = map.get("dbr").toString();
        if(StringUtils.isBlank(nextNodeDbrIds)){
            return Result.error("获取不到下一环节待办人");
        }
        SpcySqsxJob job = new SpcySqsxJob();
        job.setId(GetUuIdUtils.NotReplaceUuId());
        if(currentJob!=null){
            job.setFsyhjid(currentJob.getId());
        }
        job.setFpid(pid);
        job.setFhjmc(nextNodeName);
        if(currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }
        job.setFfssj(new Date());

        // 是否为审评查验流程 计算办理天数，是否超时状态
        if (isSpcyFlow){
            job.setFksyts(flowJobBlsxService.getSqsxSysx(pid));
            job.setFjzblsj(flowJobBlsxService.jsNodeJzrq(job.getFfssj(),job.getFksyts()));
        }

        job.setFdbrid(nextNodeDbrIds);
        job.setFdbr(nextNodeDbrs);
        job.setFydbrid(nextNodeDbrIds);
        job.setFydbr(nextNodeDbrs);

        job.setFblfs(flowConstant.getBlfs(nextNodeName));
        job.setFblzt(SpcyConstant.BLZT_DB);
        job.setFbllx(SpcyConstant.BLLX_DB);
        job.setFlcmc(flowConstant.getFlowName()); // 2023-4-3 流程名称
        spcySqsxJobService.save(job);
        return Result.ok(job);
    }

    private String getNextNodeName(FlowConstant flowConstant, String  currentNodeName, String nextNodeName){
        if (StringUtils.isNotBlank(nextNodeName)){
            return nextNodeName;
        }else{
           return flowConstant.getNextNodeName(currentNodeName);
        }
    }


}
